﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
namespace SaaS
{
    /// <summary>
    /// Summary description for searchKeywords
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class searchKeywords : System.Web.Services.WebService
    {

        [WebMethod]
        public List<string> findKeywords(string Input, double threshold)
        {
            List<string> output = new List<string>();
            MiniSaaSDB db = new MiniSaaSDB();
            SqlDataReader reader;
            db.open();
            reader = db.executeQuery("SELECT Input, Output FROM DICTIONARY");

            if (!reader.HasRows)
                return output;

            int ccount = reader.FieldCount;

            List<string> listInput = new List<string>();
            List<string> listOutput = new List<string>();

            while (reader.Read())
            {
                listInput.Add(reader[0].ToString());
                listOutput.Add(reader[1].ToString());
            }

            double[] scoreA = new double[listInput.Count];
            for (int i = 0; i < listInput.Count; i++ )
            {
                int levenshteinDistance = LevenshteinDistance(Input, listInput[i]);
                int length = Math.Max(Input.Length, listInput[i].Length);
                double score = 1.0 - (double)levenshteinDistance / length;

                if (listInput[i].IndexOf(Input)!=0)
                   scoreA[i] = score;
                else 
                    if (score>threshold)
                        scoreA[i] = score;
                    else
                        scoreA[i] = -1;
            }

            int[] indices = Enumerable.Range(0, listInput.Count).ToArray();
            Array.Sort(scoreA, indices);

            for (int i = 0; i < listInput.Count; i++)
            {
                if (scoreA[listInput.Count - i - 1] < 0)
                    return output;
                output.Add(listOutput[indices[listInput.Count - i - 1]]);
            }
            return output;
        }

        [WebMethod]
        private int LevenshteinDistance(string src, string dest)
        {
            int[,] d = new int[src.Length + 1, dest.Length + 1];
            int i, j, cost;
            char[] str1 = src.ToCharArray();
            char[] str2 = dest.ToCharArray();

            for (i = 0; i <= str1.Length; i++)
            {
                d[i, 0] = i;
            }
            for (j = 0; j <= str2.Length; j++)
            {
                d[0, j] = j;
            }
            for (i = 1; i <= str1.Length; i++)
            {
                for (j = 1; j <= str2.Length; j++)
                {

                    if (str1[i - 1] == str2[j - 1])
                        cost = 0;
                    else
                        cost = 1;

                    d[i, j] =
                        Math.Min(
                            d[i - 1, j] + 1,              // Deletion
                            Math.Min(
                                d[i, j - 1] + 1,          // Insertion
                                d[i - 1, j - 1] + cost)); // Substitution

                    if ((i > 1) && (j > 1) && (str1[i - 1] ==
                        str2[j - 2]) && (str1[i - 2] == str2[j - 1]))
                    {
                        d[i, j] = Math.Min(d[i, j], d[i - 2, j - 2] + cost);
                    }
                }
            }

            return d[str1.Length, str2.Length];
        }
    }
}
